﻿using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;
using Admin.NET.Core;

namespace Admin.NET.Application
{
    /// <summary>
    /// 库存信息服务
    /// </summary>
    [ApiDescriptionSettings("仓库作业", Name = "WmsMaterialStock", Order = 106)]
    [Route("api/[Controller]")]
    public class MaterialStockService : IDynamicApiController, ITransient
    {
        private readonly IRepository<WmsMaterialStock, MasterDbContextLocator> _wmsMaterialStockRep;
        private readonly IRepository<WmsArea> _wmsAreaRep;

        /// <summary>
        /// 构造函数
        /// </summary>
        public MaterialStockService(
            IRepository<WmsArea> wmsAreaRep,
            IRepository<WmsMaterialStock, MasterDbContextLocator> wmsMaterialStockRep
        )
        {
            _wmsAreaRep = wmsAreaRep;
            _wmsMaterialStockRep = wmsMaterialStockRep;
        }

        /// <summary>
        /// 分页查询库存表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("page")]
        public async Task<PageResult<MaterialStockOutput>> Page([FromQuery] WmsMaterialStockSearch input)
        {
            var wmsMaterialStocks = await _wmsMaterialStockRep.DetachedEntities
                .Where(!string.IsNullOrEmpty(input.MaterialNo), u => EF.Functions.Like(u.MaterialNo, $"%{input.MaterialNo.Trim()}%"))
                .Where(input.MaterialType != null, u => u.MaterialType == input.MaterialType)
                .Where(!string.IsNullOrEmpty(input.MaterialBatch), u => EF.Functions.Like(u.MaterialBatch, $"%{input.MaterialBatch.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.MaterialName), u => EF.Functions.Like(u.MaterialName, $"%{input.MaterialName.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.MaterialSpec), u => EF.Functions.Like(u.MaterialSpec, $"%{input.MaterialSpec.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.MaterialDensity), u => EF.Functions.Like(u.MaterialDensity, $"%{input.MaterialDensity.Trim()}%"))
                .Where(u => u.StockNumber != 0)
                .Where(!string.IsNullOrEmpty(input.PlaceCode), u => EF.Functions.Like(u.PlaceCode, $"%{input.PlaceCode.Trim()}%"))
                .Where(!string.IsNullOrEmpty(input.ContainerCode), u => EF.Functions.Like(u.ContainerCode, $"%{input.ContainerCode.Trim()}%"))
                .Where(input.AreaId > 0, u => u.AreaId == input.AreaId)
                .Where(input.SearchBeginTime != null && input.SearchEndTime != null, u => u.CreatedTime >= DateTime.Parse(input.SearchBeginTime.Trim()) &&
                                                                   u.CreatedTime <= DateTime.Parse(input.SearchEndTime.Trim()))
                .OrderBy(PageInputOrder.OrderBuilder<WmsMaterialStockSearch>(input))
                .ProjectToType<MaterialStockOutput>()
                .ToADPagedListAsync(input.PageNo, input.PageSize);
            //根据id获取名称
            foreach (var item in wmsMaterialStocks.Rows)
            {
                //根据库区id获取库区名称
                var data = await _wmsAreaRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == item.AreaId);
                if (data != null) item.AreaName = data.AreaName;
            }
            return wmsMaterialStocks;
        }

        /// <summary>
        /// 增加库存表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("add")]
        public async Task Add(AddMaterialStockInput input)
        {
            var wmsMaterialStock = input.Adapt<WmsMaterialStock>();
            await _wmsMaterialStockRep.InsertAsync(wmsMaterialStock);
        }

        /// <summary>
        /// 删除库存表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("delete")]
        public async Task Delete(DeleteMaterialStockInput input)
        {
            var wmsMaterialStock = await _wmsMaterialStockRep.FirstOrDefaultAsync(u => u.Id == input.Id);
            await _wmsMaterialStockRep.DeleteAsync(wmsMaterialStock);
        }

        /// <summary>
        /// 更新库存表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("edit")]
        public async Task Update(UpdateMaterialStockInput input)
        {
            var isExist = await _wmsMaterialStockRep.AnyAsync(u => u.Id == input.Id, false);
            if (!isExist) throw Oops.Oh(ErrorCode.D3000);

            var wmsMaterialStock = input.Adapt<WmsMaterialStock>();
            await _wmsMaterialStockRep.UpdateAsync(wmsMaterialStock, ignoreNullValues: true);
        }

        /// <summary>
        /// 获取库存表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("detail")]
        public async Task<MaterialStockOutput> Get([FromQuery] QueryeMaterialStockInput input)
        {
            return (await _wmsMaterialStockRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == input.Id)).Adapt<MaterialStockOutput>();
        }

        /// <summary>
        /// 获取库存表列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("list")]
        public async Task<List<MaterialStockOutput>> List([FromQuery] MaterialStockInput input)
        {
            return await _wmsMaterialStockRep.DetachedEntities.ProjectToType<MaterialStockOutput>().ToListAsync();
        }

        /// <summary>
        /// 获取WmsArea列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("WmsArea")]
        public async Task<dynamic> FkWmsAreaList()
        {
            var list = await _wmsAreaRep.DetachedEntities.ToListAsync();
            return list.Select(e => new { Code = e.Id, Name = e.AreaName });
        }
    }
}
